#ifndef GRAMMAR_H
#define GRAMMAR_H

#include "GOAL.h"
#include "Code_Lines.h"
#include "Code_Line.h"
#include "UmlExt.h"

namespace GOAL
  {
  class Grammar
    {
    public:
      class RegularExpression
        {
        public:
          RegularExpression (Code_Line &code_line);
          Code_Line & code_line_;
        };

      class Assignment : public RegularExpression
        {
        public:
          Assignment (Code_Line &code_line, Code_Line::iterator assign);
          Code_Line::iterator assign_;
        };

      class ConsolePrint : public Assignment
        {
        public:
          ConsolePrint (Code_Line &code_line, Code_Line::iterator assign);
        };

      class InputLine : public Assignment
        {
        public:
          InputLine (Code_Line &code_line, Code_Line::iterator assign);
        };

      class RhsElement
        {
        public:
          GOAL::MgaObject object;
        };

      class LhsElement
        {
        public:
          GOAL::MgaObject object;
        };

      class InputElement
        {
        public:
          GOAL::MgaObject object;
        };

      class FunctionCallLine
        {
        public:
          GOAL::FunctionCall object;
        };

      class Info
        {
        public: 
          Info (Code_Line& code_line);
          Info (Info& info);
          int confidence;
          Code_Line::iterator pos;
        };

      Grammar ();

      static void init (void);

      static bool isLhs (const Uml::Class &);
      static bool isRhs (const Uml::Class &);
      static bool isAssignment (const Uml::Class &);
      static bool isConnection (const Uml::Class &);
      static bool isAccumulator (const Uml::Class &);
      static bool isBooleanOperator (const Uml::Class &);
      static bool isStandalone (const Uml::Class &);
      static bool isInput (const Uml::Class &);
      static bool isOutput (const Uml::Class &);
      static bool isClass (const Uml::Class &);
      static bool isAssignmentLine (Code_Line & line, Info& info);
      static bool isConsolePrintout (Code_Line & line, Info& info);
      static bool isInputLine (Code_Line & line, Info& info);
      static bool isFunctionCall (Code_Line & line, Info& info);

      static std::map <std::string,bool> lhs_types;
      static std::map <std::string,bool> rhs_types;
      static std::map <std::string,bool> assignment_types;
      static std::map <std::string,bool> accumulator_types;
      static std::map <std::string,bool> connection_types;
      static std::map <std::string,bool> boolean_operator_types;
      static std::map <std::string,bool> standalone_types;
      static std::map <std::string,bool> output_types;
      static std::map <std::string,bool> input_types;

      static bool initialized_;

    };
  }

#endif